home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcr
/
pcr4_4.lha
/
DIST
/
loading
/
IncrementalLoadADotOut.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-04
|
27KB
|
894 lines
/* begincopyright
Copyright (c) 1988 Xerox Corporation. All rights reserved.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to:
PCR Coordinator
Xerox PARC
3333 Coyote Hill Rd.
Palo Alto, CA 94304
endcopyright */
/*
* IncrementalLoadADotOut.c
*
* Incremental loading proc for a.out files.
* Currently implemented for: sparc.
*
* Demers, July 10, 1990 1:33:36 pm PDT
* Aizawa January 5, 1990 3:09:39 pm PST
*
* Note this code presumes some correspondence
* between ILSE_xxx and N_xxx typecodes.
*/
#ifdef UNIXDEBUG
# include <stdio.h>
#endif
#define RELOC_UNDF_EXT_ONLY 0
#include "xr/BasicTypes.h"
#include "xr/IncrementalLoad.h"
#include "xr/IncrementalLoadPrivate.h"
#include "xr/Errno.h"
#include "xr/PZone.h"
#include "xr/BldSymX.h"
#include <sys/types.h>
#include <string.h>
#ifndef N_BADMAG
# include <a.out.h>
#endif
#ifndef N_GSYM
# include <stab.h>
#endif
#ifdef sparc
# define RelocInfo struct reloc_info_sparc
# define MACHTYPE M_SPARC
#else
--> fix me <--
#endif
/* file-type-specific temp fields of the il sym tab structure */
#define XR_ILAOExec(ilst) ((struct exec **)(ilst->ilst_fileData))[0]
#define XR_ILAOText(ilst) ((char **)(ilst->ilst_fileData))[1]
#define XR_ILAOData(ilst) ((char **)(ilst->ilst_fileData))[2]
#define XR_ILAOTReloc(ilst) ((RelocInfo **)(ilst->ilst_fileData))[3]
#define XR_ILAODReloc(ilst) ((RelocInfo **)(ilst->ilst_fileData))[4]
#define XR_ILAOSymsx(ilst) ((struct nlistx **)(ilst->ilst_fileData))[5]
#define XR_ILAONSymsx(ilst) ((unsigned *)(ilst->ilst_fileData))[6]
#define XR_ILAOStrings(ilst) ((char **)(ilst->ilst_fileData))[8]
#define ErrRes(ilst,m) { XR_ILSetError(ilst, TRUE, ENOEXEC, (m)); return; }
#define CheckRes2(ilst,stmt) if( (ilst)->ilst_result != NIL ) stmt
#define CheckRes(ilst) CheckRes2(ilst,return)
#define SetRes2(ilst,fatal,code,msg,stmt) \
{ XR_ILSetError((ilst),(fatal),(code),(msg)); stmt; }
#define ROUNDUPWORD(x) \
( (((unsigned)(x))+(sizeof(int)-1)) & (~(sizeof(int)-1)) )
/*
* I/O
*/
static void
XR_ILAOReadExec(ilst)
XR_ILSymTab ilst;
{
struct exec *a;
a = (struct exec *)
XR_PZmalloc( ilst->ilst_zonePerFile, sizeof(struct exec) );
if( a == NIL ) {
XR_ILSetError(ilst, TRUE, ENOMEM, "ILAOReadExec out of memory");
return;
}
XR_ILRead(ilst, 0, a, sizeof(struct exec), FALSE);
CheckRes(ilst);
/* check magic number and cpu type */
{ unsigned m = ilst->ilst_ilfte->ilfte_ilfe.ilfe_fMagic;
if( N_BADMAG(*a) ) {
XR_ILSetError(ilst, FALSE, EDOM, "ILAOReadExec file not a.out");
return;
}
if( a->a_machtype != MACHTYPE ) {
XR_ILSetError(ilst, FALSE, ENOEXEC,
"ILAOReadExec file wrong machine type");
return;
}
if( (m != 0) && (a->a_magic != m) ) {
XR_ILSetError(ilst, FALSE, ENOEXEC,
"ILAOReadExec file wrong magic number");
return;
}
ilst->ilst_ilfte->ilfte_ilfe.ilfe_fMagic = a->a_magic;
}
/* check to be sure file is not stripped! */
{
if( (a->a_syms == 0) && (a->a_trsize == 0)
&& (a->a_drsize == 0) ) {
XR_ILSetError(ilst, FALSE, ENOEXEC,
"ILAOReadExec stripped file");
return;
}
}
XR_ILAOExec(ilst) = a;
}
static char *
XR_ILAOSymXAllocProc(clientData, sxd)
char *clientData;
XR_SymXData sxd;
{
XR_ILSymTab ilst = ((XR_ILSymTab)(clientData));
if( sxd->sxd_nsymsx > 0 ) {
sxd->sxd_symsx = (struct nlistx *) XR_PZmalloc(
ilst->ilst_zonePerFile, sxd->sxd_nsymsx * sizeof(struct nlistx) );
if( sxd->sxd_symsx == NIL )
return "ILAOSymXAllocProc no memory for syms";
}
if( sxd->sxd_nstringsx > 0 ) {
sxd->sxd_stringsx = (char *) XR_PZmalloc(
ilst->ilst_zonePtrFree, sxd->sxd_nstringsx );
if( sxd->sxd_stringsx == NIL )
return "ILAOSymXAllocProc no memory for strings";
}
if( sxd->sxd_nstabs > 0 ) {
sxd->sxd_stabs = (struct dbxstabs *) XR_PZmalloc(
ilst->ilst_zonePtrFree, sxd->sxd_nstabs * sizeof(struct dbxstabs) );
if( sxd->sxd_stabs == NIL )
return "ILAOSymXAllocProc no memory for dbx stabs";
}
return NIL;
}
static void
XR_ILAORelocateSymsX(ilst)
XR_ILSymTab ilst;
{
struct nlistx *p, *pLim;
p = XR_ILAOSymsx(ilst);
pLim = p + XR_ILAONSymsx(ilst);
while( p < pLim ) {
if( p->nx_n.n_un.n_strx != 0 ) {
p->nx_n.n_un.n_name = XR_ILAOStrings(ilst) + p->nx_n.n_un.n_strx;
}
p++;
}
}
static void
XR_ILAOReadRawSymbolsAndStrings(ilst)
XR_ILSymTab ilst;
{
XR_ILFileEntry ilfe = &(ilst->ilst_ilfte->ilfte_ilfe);
struct exec *a = XR_ILAOExec(ilst);
struct XR_SymXDataRep sxd;
unsigned nRawSyms = 0;
unsigned rawStringBytes;
char *bldAns;
XR_PZone z;
z = XR_PZCreate( TRUE, 0 );
(void) bzero( ((char *)(&sxd)), (sizeof sxd) );
sxd.sxd_hdr = a;
if( a->a_syms == 0 ) {
sxd.sxd_syms = NIL;
} else {
sxd.sxd_syms = (struct nlist *) XR_PZmalloc( z, a->a_syms );
if( sxd.sxd_syms == NIL ) {
SetRes2( ilst, TRUE, ENOMEM,
"ILAOReadRawSymbolsAndStrings no memory for raw syms",
goto CleanUp );
}
XR_ILRead(ilst, N_SYMOFF(*a), sxd.sxd_syms, a->a_syms, FALSE);
CheckRes2(ilst, goto CleanUp);
}
XR_ILRead(ilst, N_STROFF(*a), &rawStringBytes,
(sizeof rawStringBytes), FALSE);
CheckRes2(ilst, goto CleanUp);
sxd.sxd_strings = (char *) XR_PZmalloc(z, rawStringBytes );
if( sxd.sxd_strings == NIL ) {
SetRes2( ilst, TRUE, ENOMEM,
"ILAOReadRawSymbolsAndStrings no memory for raw strings",
goto CleanUp );
}
XR_ILRead(ilst, N_STROFF(*a), sxd.sxd_strings, rawStringBytes, FALSE);
CheckRes2(ilst, goto CleanUp);
bldAns = XR_BldSymX( &sxd, XR_ILAOSymXAllocProc, ((char *)(ilst)), FALSE );
if( bldAns != NIL ) {
SetRes2( ilst, FALSE, ENOEXEC,
"ILAOReadRawSymbolsAndStrings BldSymX failed",
goto CleanUp );
}
XR_ILAONSymsx(ilst) = sxd.sxd_nsymsx;
XR_ILAOSymsx(ilst) = sxd.sxd_symsx;
XR_ILAOStrings(ilst) = sxd.sxd_stringsx;
XR_ILAORelocateSymsX(ilst);
ilfe->ilfe_rdrDataBytes = sxd.sxd_nstabs * sizeof(struct dbxstabs);
ilfe->ilfe_rdrData = (caddr_t) sxd.sxd_stabs;
CleanUp:
XR_PZrevert( z, XR_PZ_FREE_ALL );
}
#ifdef UNDEFINED
static void
XR_ILAOReadSymbolsAndStrings(ilst)
XR_ILSymTab ilst;
{
struct hdrx hx;
unsigned pos, hxpos;
unsigned stringBytes, nSymsx;
XR_Pointer dbxSTABs;
XR_ILFileEntry ilfe = &(ilst->ilst_ilfte->ilfte_ilfe);
struct exec *a = XR_ILAOExec(ilst);
pos = N_STROFF(*a);
XR_ILRead(ilst, pos, &stringBytes, (sizeof stringBytes), FALSE);
CheckRes(ilst);
hxpos = ROUNDUPWORD(pos + stringBytes);
XR_ILRead(ilst, hxpos, &hx, (sizeof hx), FALSE);
CheckRes2(ilst, goto ReadRaw);
if( !HDRX_OK(hx) ) goto ReadRaw;
XR_ILAOSymsx(ilst) = NIL;
if( hx.hx_symBytes > 0 ) {
XR_ILAOSymsx(ilst) = (struct nlistx *)
XR_PZmalloc( ilst->ilst_zonePerFile, hx.hx_symBytes );
if( XR_ILAOSymsx(ilst) == NIL ) {
SetRes2(ilst, TRUE, ENOMEM,
"ILAOReadSymbolsAndStrings no memory for syms",
return );
}
pos = hxpos + NX_SECTRELOFF(hx, HDRX_SYM_SECTION);
XR_ILRead(ilst, pos, XR_ILAOSymsx(ilst), hx.hx_symBytes, FALSE);
CheckRes2(ilst, goto ReadRaw);
}
XR_ILAONSymsx(ilst) = hx.hx_symBytes / sizeof(struct nlistx);
XR_ILAOStrings(ilst) = (char *)
XR_PZmalloc( ilst->ilst_zonePtrFree, hx.hx_strBytes );
if( XR_ILAOStrings(ilst) == NIL ) {
SetRes2(ilst, TRUE, ENOMEM,
"ILAOReadSymbolsAndStrings no memory for strings",
return );
}
pos = hxpos + NX_SECTRELOFF(hx, HDRX_STR_SECTION);
XR_ILRead(ilst, pos, XR_ILAOStrings(ilst), hx.hx_strBytes, FALSE);
CheckRes2(ilst, goto ReadRaw);
XR_ILAORelocateSymsX(ilst);
if( hx.hx_dbxSTABBytes == 0 ) goto NoDBXSTABs;
dbxSTABs = (XR_Pointer)
XR_PZmalloc( ilst->ilst_zonePtrFree, hx.hx_dbxSTABBytes );
if( dbxSTABs == NIL ) {
SetRes2(ilst, TRUE, ENOMEM,
"ILAOReadSymbolsAndStrings no memory for dbx stabs",
return );
}
pos = hxpos + NX_SECTRELOFF(hx, HDRX_DBXSTAB_SECTION);
XR_ILRead(ilst, pos, ((char *)(dbxSTABs)), hx.hx_dbxSTABBytes, FALSE);
CheckRes2(ilst, goto NoDBXSTABs);
ilfe->ilfe_rdrDataBytes = hx.hx_dbxSTABBytes;
ilfe->ilfe_rdrData = (caddr_t) dbxSTABs;
return;
NoDBXSTABs:
ilfe->ilfe_rdrDataBytes = 0;
ilfe->ilfe_rdrData = NIL;
return;
ReadRaw:
ilst->ilst_result = NIL;
XR_ILAOSymsx(ilst) = NIL;
XR_ILAONSymsx(ilst) = 0;
XR_ILAOStrings(ilst) = NIL;
XR_ILAOReadRawSymbolsAndStrings(ilst);
return;
}
#else
static int
XR_ILAOXLSeekProc(pos, whence, ilst)
int pos;
int whence;
XR_ILSymTab ilst;
{
static int buf;
if( whence != L_SET ) {
XR_ConsoleMsg("XR_ILAOXLSeekProc whence botch %d\n", whence);
return(-1);
}
XR_ILRead(ilst, pos, buf, 0, FALSE);
CheckRes2(ilst, return(-1));
}
static int
XR_ILAOXReadProc(buf, nbytes, ilst)
char *buf;
int nbytes;
XR_ILSymTab ilst;
{
XR_ILRead(ilst, (-1), buf, nbytes, FALSE);
CheckRes2(ilst, return(-1));
}
static void
XR_ILAOReadSymbolsAndStrings(ilst)
XR_ILSymTab ilst;
{
int ans;
int subsecPos, subsecBytes;
int stringsxPos, stringsxBytes;
int nlistxPos, nlistxBytes;
int stabsPos, stabsBytes;
XR_Pointer dbxSTABs;
XR_ILFileEntry ilfe = &(ilst->ilst_ilfte->ilfte_ilfe);
ans = XR_FindExtraSubsec(
XR_ILAOXLSeekProc, XR_ILAOXReadProc, ilst,
ILSymsXSubsecName, &subsecPos, &subsecBytes );
if( (ans < 0) || (subsecPos == 0) ) goto ReadRaw;
stringsxPos = subsecPos;
XR_ILRead(ilst, stringsxPos, &stringsxBytes, (sizeof stringsxBytes), FALSE);
CheckRes2(ilst, goto ReadRaw);
stringsxPos += (sizeof stringsxBytes);
stringsxBytes -= (sizeof stringsxBytes);
nlistxPos = ROUNDUPWORD(stringsxPos + stringsxBytes);
XR_ILRead(ilst, nlistxPos, nlistxBytes, (sizeof nlistxBytes), FALSE);
CheckRes2(ilst, goto ReadRaw);
nlistxPos += (sizeof nlistxBytes);
nlistxBytes -= (sizeof nlistxBytes);
XR_ILAOSymsx(ilst) = NIL;
if( nlistxBytes > 0 ) {
XR_ILAOSymsx(ilst) = (struct nlistx *)
XR_PZmalloc( ilst->ilst_zonePerFile, nlistxBytes );
if( XR_ILAOSymsx(ilst) == NIL ) {
SetRes2(ilst, TRUE, ENOMEM,
"ILAOReadSymbolsAndStrings no memory for syms",
return );
}
XR_ILRead(ilst, nlistxPos, XR_ILAOSymsx(ilst), nlistxBytes, FALSE);
CheckRes2(ilst, goto ReadRaw);
}
XR_ILAONSymsx(ilst) = nlistxBytes / sizeof(struct nlistx);
XR_ILAOStrings(ilst) = (char *)
XR_PZmalloc( ilst->ilst_zonePtrFree, stringsxBytes );
if( XR_ILAOStrings(ilst) == NIL ) {
SetRes2(ilst, TRUE, ENOMEM,
"ILAOReadSymbolsAndStrings no memory for strings",
return );
}
XR_ILRead(ilst, stringsxPos, XR_ILAOStrings(ilst), stringsxBytes, FALSE);
CheckRes2(ilst, goto ReadRaw);
XR_ILAORelocateSymsX(ilst);
ans = XR_FindExtraSubsec(
XR_ILAOXLSeekProc, XR_ILAOXReadProc, ilst,
STABGrpsXSubsecName, &stabsPos, &stabsBytes );
if( (ans < 0) || (stabsPos == 0) ) goto NoDBXSTABs;
dbxSTABs = (XR_Pointer)
XR_PZmalloc( ilst->ilst_zonePtrFree, stabsBytes );
if( dbxSTABs == NIL ) {
SetRes2(ilst, TRUE, ENOMEM,
"ILAOReadSymbolsAndStrings no memory for dbx stabs",
return );
}
XR_ILRead(ilst, stabsPos, ((char *)(dbxSTABs)), stabsBytes, FALSE);
CheckRes2(ilst, goto NoDBXSTABs);
ilfe->ilfe_rdrDataBytes = stabsBytes;
ilfe->ilfe_rdrData = (caddr_t) dbxSTABs;
return;
NoDBXSTABs:
ilfe->ilfe_rdrDataBytes = 0;
ilfe->ilfe_rdrData = NIL;
return;
ReadRaw:
ilst->ilst_result = NIL;
XR_ILAOSymsx(ilst) = NIL;
XR_ILAONSymsx(ilst) = 0;
XR_ILAOStrings(ilst) = NIL;
XR_ILAOReadRawSymbolsAndStrings(ilst);
return;
}
#endif
static struct nlistx *
XR_ILAOGetSymxFromIndex(ilst, index)
XR_ILSymTab ilst;
unsigned index;
{
int l, r, m;
struct nlistx *symsx, *pm;
symsx = XR_ILAOSymsx(ilst);
l = 0;
r = ((int)(XR_ILAONSymsx(ilst))) - 1;
while( l <= r ) {
m = (l + r) / 2;
pm = symsx + m;
if( pm->nx_x == index ) return pm;
else if( pm->nx_x < index ) l = m + 1;
else /* pm->nx_x > index */ r = m - 1;
}
return NIL;
}
static void
XR_ILAOAllocSegments(ilst)
XR_ILSymTab ilst;
{
struct exec *a = XR_ILAOExec(ilst);
XR_ILAllocSegments( ilst, a->a_text, a->a_data, a->a_bss );
CheckRes(ilst);
}
static void
XR_ILAOReadSegments(ilst)
XR_ILSymTab ilst;
{
XR_ILFileTabEntry ilfte = ilst->ilst_ilfte;
struct exec *a = XR_ILAOExec(ilst);
if( ilfte->ilfte_ilfe.ilfe_tBytes > 0 ) {
XR_ILRead( ilst, N_TXTOFF(*a),
ilfte->ilfte_ilfe.ilfe_tAddr,
ilfte->ilfte_ilfe.ilfe_tBytes, FALSE );
CheckRes(ilst);
}
if( ilfte->ilfte_ilfe.ilfe_dBytes > 0 ) {
XR_ILRead(ilst, N_DATOFF(*a),
ilfte->ilfte_ilfe.ilfe_dAddr,
ilfte->ilfte_ilfe.ilfe_dBytes, FALSE);
CheckRes(ilst);
}
}
/*
* Create an external MODULE symbol for this file.
* Put all external, text and MODULE symbols into XR_ilSymTab.
* Set n_un.n_name field to point to entry in XR_ilSymTab.
* Fix up values of other symbols (not really necessary).
*/
static void
XR_ILAOProcessSymbols(ilst)
XR_ILSymTab ilst;
{
XR_ILFileEntry ilfe;
struct exec *a;
struct nlistx *px, *pxLim;
unsigned tReloc, dReloc, bReloc;
XR_ILSymTabEntry prevModuleEntry, thisModuleEntry, thisPatchEntry;
char *ilfeShortName;
# if (_FN != (N_FN & N_TYPE))
/* this is a pre-4.1 compilation (delete this after 4.1) */
int pre4Dot1ErrMsgCnt = 0;
# endif
# ifdef UNIXDEBUG
printf("ILAOProcessSymbols() nSymsx %d\n", XR_ILAONSymsx(ilst));
# endif
ilfe = &(ilst->ilst_ilfte->ilfte_ilfe);
a = XR_ILAOExec(ilst);
tReloc = (unsigned)(ilfe->ilfe_tAddr);
dReloc = (unsigned)(ilfe->ilfe_dAddr - a->a_text);
bReloc = (unsigned)(ilfe->ilfe_bAddr - a->a_text - a->a_data);
if( (ilfeShortName = strrchr(ilfe->ilfe_fName, '/')) != NIL ) {
ilfeShortName += 1;
} else {
ilfeShortName = ilfe->ilfe_fName;
}
/* Create MODULE|EXT symbol for the entire file ... */
thisModuleEntry = XR_ILSetSymDefined(
ilst,
ilfeShortName, XR_ILHashFromSym(ilfeShortName),
(ILSE_MODULE|ILSE_EXT), tReloc);
if( thisModuleEntry == NIL ) return;
thisModuleEntry->ilste_ilse.ilse_size = a->a_text;
/* Create PATCH|EXT symbol if there is a patch area ... */
if( ilfe->ilfe_pBytes > 0 ) {
thisPatchEntry = XR_ILSetSymDefined(
ilst,
ilfeShortName, XR_ILHashFromSym(ilfeShortName),
(ILSE_PATCH|ILSE_EXT), ilfe->ilfe_pAddr);
if( thisPatchEntry == NIL ) return;
thisPatchEntry->ilste_ilse.ilse_size = ilfe->ilfe_pBytes;
}
/* Process the symbol table ... */
px = XR_ILAOSymsx(ilst);
pxLim = px + XR_ILAONSymsx(ilst);
prevModuleEntry = NIL;
while( px < pxLim ) {
char *sym;
unsigned hash;
sym = px->nx_n.n_un.n_name;
hash = XR_ILHashFromSym(sym);
switch( px->nx_n.n_type & N_TYPE ) {
case (N_FN & N_TYPE):
/* "&N_TYPE" fixes bug in pre-4.1 <sun4/a.out.h> */
/* Delete the following after 4.1 */
# if (N_FN == (N_FN & N_TYPE))
/* this is 4.1 or later */
break;
# else
/* this is pre-4.1 */
if( pre4Dot1ErrMsgCnt == 0 ) {
XR_ConsoleMsg( "ILADotOut: sym type 0x%x\n",
px->nx_n.n_type & N_TYPE );
pre4Dot1ErrMsgCnt += 1;
}
/* fall thru and treat it like N_MODULE */
# endif
case N_MODULE:
thisModuleEntry = XR_ILSetSymDefined(
ilst, sym, hash, ILSE_MODULE,
px->nx_n.n_value + tReloc);
if( thisModuleEntry == NIL ) return;
thisModuleEntry->ilste_ilse.ilse_size = (
tReloc + ilfe->ilfe_tBytes
- thisModuleEntry->ilste_ilse.ilse_value
/* upper bound -- updated just below */
);
if( prevModuleEntry != NIL ) {
prevModuleEntry->ilste_ilse.ilse_size = (
thisModuleEntry->ilste_ilse.ilse_value
- prevModuleEntry->ilste_ilse.ilse_value
);
}
prevModuleEntry = thisModuleEntry;
px->nx_n.n_type = N_TEXT;
/* FALL THRU to N_TEXT case ... */
case N_TEXT:
px->nx_n.n_value += tReloc;
px->nx_n.n_un.n_name = (char *) XR_ILSetSymDefined(
ilst, sym, hash, px->nx_n.n_type, px->nx_n.n_value);
if( px->nx_n.n_un.n_name == NIL ) return;
break;
case N_DATA:
px->nx_n.n_value += dReloc;
if( px->nx_n.n_type & N_EXT ) {
px->nx_n.n_un.n_name = (char *) XR_ILSetSymDefined(
ilst, sym, hash, px->nx_n.n_type, px->nx_n.n_value);
if( px->nx_n.n_un.n_name == NIL ) return;
}
break;
case N_BSS:
px->nx_n.n_value += bReloc;
if( px->nx_n.n_type & N_EXT ) {
px->nx_n.n_un.n_name = (char *) XR_ILSetSymDefined(
ilst, sym, hash, px->nx_n.n_type, px->nx_n.n_value);
if( px->nx_n.n_un.n_name == NIL ) return;
}
break;
case N_ABS:
if( px->nx_n.n_type & N_EXT ) {
px->nx_n.n_un.n_name = (char *) XR_ILSetSymDefined(
ilst, sym, hash, px->nx_n.n_type, px->nx_n.n_value);
if( px->nx_n.n_un.n_name == NIL ) return;
}
break;
case N_UNDF:
if( !(px->nx_n.n_type & N_EXT) ) {
ErrRes(ilst, "undefined internal symbol found");
}
if( px->nx_n.n_value != 0 ) {
px->nx_n.n_un.n_name = (char *) XR_ILSetSymCommon(
ilst, sym, hash, px->nx_n.n_value);
if( px->nx_n.n_un.n_name == NIL ) return;
} else {
px->nx_n.n_un.n_name = (char *) XR_ILSetSymReferenced(
ilst, sym, hash);
if( px->nx_n.n_un.n_name == NIL ) return;
}
break;
default:
ErrRes( ilst, "unknown symbol type found" );
}
px++;
}
}
static void
XR_ILAOReadRelocationInfo(ilst)
XR_ILSymTab ilst;
{
struct exec *a = XR_ILAOExec(ilst);
XR_ILAOTReloc(ilst) = NIL;
if( a->a_trsize > 0 ) {
XR_ILAOTReloc(ilst) = (RelocInfo *)
XR_PZmalloc(ilst->ilst_zonePerFile, a->a_trsize);
if( XR_ILAOTReloc(ilst) == NIL ) {
SetRes2(ilst, TRUE, ENOMEM,
"ILAOReadRelocationInfo no memory for text reloc",
return );
}
XR_ILRead( ilst, N_TRELOFF(*a),
XR_ILAOTReloc(ilst), a->a_trsize, TRUE );
CheckRes(ilst);
}
XR_ILAODReloc(ilst) = NIL;
if( a->a_drsize > 0 ) {
XR_ILAODReloc(ilst) = (RelocInfo *)
XR_PZmalloc(ilst->ilst_zonePerFile, a->a_drsize);
if( XR_ILAODReloc(ilst) == NIL ) {
SetRes2(ilst, TRUE, ENOMEM,
"ILAOReadRelocationInfo no memory for data reloc",
return );
}
XR_ILRead( ilst, N_DRELOFF(*a),
XR_ILAODReloc(ilst), a->a_drsize, TRUE );
CheckRes(ilst);
}
}
#ifdef sparc
static void
XR_ILAORelocateProc(addr, relocType, addend, val)
char *addr;
unsigned relocType;
long addend;
unsigned val;
{
long relocVal;
# define MemInsert(p,v,shift,mask) *((long *)(p)) = \
( (*((long *)(p)) & (mask)) | ((((long)(v)) >> (shift)) & (~(mask))) )
relocVal = addend + val;
switch( relocType ) {
case RELOC_8:
case RELOC_DISP8:
*((char *)(addr)) = relocVal;
break;
case RELOC_16:
case RELOC_DISP16:
*((short *)(addr)) = relocVal;
break;
case RELOC_32:
case RELOC_DISP32:
*((long *)(addr)) = relocVal;
break;
case RELOC_WDISP30:
MemInsert(addr,relocVal,2,0xc0000000);
break;
case RELOC_WDISP22:
MemInsert(addr,relocVal,2,0xffc00000);
break;
case RELOC_HI22:
MemInsert(addr,relocVal,10,0xffc00000);
break;
case RELOC_22:
MemInsert(addr,relocVal,0,0xffc00000);
break;
case RELOC_13:
MemInsert(addr,relocVal,0,0xffffe000);
break;
case RELOC_LO10:
MemInsert(addr,relocVal,0,0xfffffc00);
break;
case RELOC_SFA_BASE:
ErrRes(XR_ilSymTab, "reloc RELOC_SFA_BASE?" );
case RELOC_SFA_OFF13:
ErrRes(XR_ilSymTab, "reloc RELOC_SFA_OFF13?" );
case RELOC_SEGOFF16:
ErrRes(XR_ilSymTab, "reloc RELOC_SEGOFF16?" );
default:
ErrRes(XR_ilSymTab, "unknown reloc" );
}
}
static void
XR_ILAORelocateInner(ilst, seg)
XR_ILSymTab ilst;
unsigned seg;
{
RelocInfo *rp, *rpLim;
unsigned tReloc, dReloc, bReloc, segReloc, segBase;
char *addr;
unsigned addend;
struct exec *a;
struct nlistx *nxp;
XR_ILFileEntry ilfe;
XR_ILSymTabEntry ilste;
ilfe = &(ilst->ilst_ilfte->ilfte_ilfe);
a = XR_ILAOExec(ilst);
tReloc = (unsigned)(ilfe->ilfe_tAddr);
dReloc = (unsigned)(ilfe->ilfe_dAddr - a->a_text);
bReloc = (unsigned)(ilfe->ilfe_bAddr - a->a_text - a->a_data);
switch(seg) {
case N_TEXT:
rp = XR_ILAOTReloc(ilst);
rpLim = (RelocInfo *)( ((char *)(rp)) + a->a_trsize );
segBase = (unsigned)(ilfe->ilfe_tAddr);
segReloc = tReloc;
break;
case N_DATA:
rp = XR_ILAODReloc(ilst);
rpLim = (RelocInfo *)( ((char *)(rp)) + a->a_drsize );
segBase = (unsigned)(ilfe->ilfe_dAddr);
segReloc = dReloc;
break;
default:
ErrRes(ilst, "internal error (ILAORelocateInner)" );
}
for( ; rp < rpLim; rp++ ) {
addr = (char *)(segBase + rp->r_address);
addend = rp->r_addend;
switch( rp->r_type ) {
case RELOC_DISP8:
case RELOC_DISP16:
case RELOC_DISP32:
case RELOC_WDISP30:
case RELOC_WDISP22:
addend -= segReloc;
break;
default:
break;
}
if( rp->r_extern ) {
nxp = XR_ILAOGetSymxFromIndex(ilst, rp->r_index);
XR_ILAssert( (nxp != NIL), "ILAORelocateInner a0" );
# if RELOC_UNDF_EXT_ONLY
if( nxp->nx_n.n_type != (N_UNDF|N_EXT) ) {
ErrRes(ilst, "ILAORelocateInner: reloc not undef extern");
}
# endif
ilste = (XR_ILSymTabEntry)(nxp->nx_n.n_un.n_name);
XR_ILRelocate(ilst, ilste, XR_ILAORelocateProc,
addr, rp->r_type, addend);
CheckRes(ilst);
} else {
switch( rp->r_index ) {
case N_TEXT:
addend += tReloc;
break;
case N_DATA:
addend += dReloc;
break;
case N_BSS:
addend += bReloc;
break;
case N_ABS:
/* This does happen ... but does it make sense? */
break;
default:
ErrRes(ilst, "ILAORelocateInner: reloc bad seg");
}
XR_ILAORelocateProc(addr, rp->r_type, addend, 0);
CheckRes(ilst);
}
}
}
#else
--> fix me for this (non-sparc) architecture <--
#endif
static void
XR_ILAORelocate(ilst)
XR_ILSymTab ilst;
{
XR_ILAORelocateInner(ilst, N_TEXT);
CheckRes(ilst);
XR_ILAORelocateInner(ilst, N_DATA);
CheckRes(ilst);
}
#define CALL(f) { XR_/**/f(ilst); CheckRes(ilst); }
static void
XR_IncrementalLoadADotOut(ilst)
XR_ILSymTab ilst;
{
XR_ILOp op = ilst->ilst_opArg;
switch( op ) {
case ilOpInternalize:
case ilOpLoad:
CALL(ILGetOpenFile);
CALL(ILAOReadExec);
CALL(ILAOAllocSegments);
if( op == ilOpLoad ) CALL(ILAOReadSegments);
CALL(ILAOReadSymbolsAndStrings);
CALL(ILAOProcessSymbols);
if( op == ilOpLoad ) CALL(ILAOReadRelocationInfo);
if( op == ilOpLoad ) CALL(ILAORelocate);
break;
case ilOpCommit:
break;
case ilOpAbort:
break;
default:
XR_Panic("IncrementalLoadADotOut bad op");
}
}
#undef CALL
static unsigned XR_ILAOMagics[] = { OMAGIC, NMAGIC, ZMAGIC };
static unsigned XR_ILAONMagics =
(sizeof XR_ILAOMagics)/(sizeof XR_ILAOMagics[0]);
void
XR_run_IncrementalLoadADotOut()
{
XR_RegisterIncrementalLoadProc(
XR_IncrementalLoadADotOut, NIL, XR_ILAOMagics, XR_ILAONMagics
);
}
void
XR_run_IncrementalLoadDEFAULT()
{
XR_RegisterIncrementalLoadProc(
XR_IncrementalLoadADotOut, NIL, XR_ILAONMagics, XR_ILAOMagics
);
}